﻿/*
 * Copyright (c) 2011
 * Thomas Rozanski, Geoffrey Wright, Zachary Lynn, Jesse Natalie
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the team nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THOMAS ROZANSKI, GEOFFREY WRIGHT,
 * ZACHARY LYNN, OR JESSE NATALIE BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Kinected;

namespace Pinball
{
    /// <summary>Draws the depth and color images to the screen.</summary>
    public class Overlay
    {
        private enum ImageType { Depth, Color }
        private enum DisplayMode { Off, Small, Large, OutOfBounds }

        private int windowWidth, windowHeight;

        private RGBAImage rgbaImage;
        private Texture2D kinectImage, overlayFrame;
        private Vector2 depthOrigin;

        private DisplayMode displayMode;
        private ImageType imageType;

        /// <param name="width">Width of the images that we will be using.</param>
        /// <param name="height">Height of the images that we will be using.</param>
        public Overlay(GraphicsDevice graphicsDevice, int width, int height, int windowWidth, int windowHeight)
        {
            displayMode = DisplayMode.Small;
            imageType = ImageType.Color;

            this.windowWidth = windowWidth;
            this.windowHeight = windowHeight;

            // Initialize overlay
            rgbaImage = new RGBAImage(width, height);
            depthOrigin = new Vector2(width / 2, height / 2);
            kinectImage = new Texture2D(graphicsDevice, width, height, false, SurfaceFormat.Color);
        }

        /// <summary>Load the overlay assets.</summary>
        public void LoadContent(ContentManager Content)
        {
            overlayFrame = Content.Load<Texture2D>("interface/overlayFrame");
        }

        /// <summary>Update the overlay.</summary>
        /// <param name="controller">For changing the overview settings.</param>
        /// <param name="rgbaColorImage">The color image.</param>
        /// <param name="rgbaDepthImage">The depth image.</param>
        /// <param name="haveNewCameraImage">Is there a new image?</param>
        public void Update(Controller controller, RGBAImage rgbaColorImage, RGBAImage rgbaDepthImage, bool haveNewCameraImage)
        {
            if (controller.KeyPress(Keys.O))
            {
                displayMode++;

                if (displayMode == DisplayMode.OutOfBounds)
                {
                    displayMode = DisplayMode.Off;
                }
            }

            if (controller.KeyPress(Keys.D1))
            {
                imageType = ImageType.Depth;
            }

            if (controller.KeyPress(Keys.D2))
            {
                imageType = ImageType.Color;
            }

            if (haveNewCameraImage && displayMode != DisplayMode.Off)
            {
                if (imageType == ImageType.Color)
                {
                    rgbaImage = rgbaColorImage;
                }
                else
                {
                    rgbaImage = rgbaDepthImage;
                }

                // Update the texture
                kinectImage.SetData(rgbaImage.Data);
            }
        }

        /// <summary>Draw the overlay to the screen.</summary>
        public void Draw(SpriteBatch spriteBatch)
        {
            if (displayMode == DisplayMode.Small)
            {
                spriteBatch.Draw(overlayFrame, new Vector2(windowWidth-314, 48), Color.White);
                spriteBatch.Draw(kinectImage, new Vector2(windowWidth-180, 150), null, Color.White, 0.0f, depthOrigin, 0.4f, SpriteEffects.None, 0);
            }
            else if (displayMode == DisplayMode.Large)
            {
                spriteBatch.Draw(overlayFrame, new Rectangle(windowWidth - 703, 40, 665, 505), Color.White);
                spriteBatch.Draw(kinectImage, new Vector2(windowWidth - 370, 292), null, Color.White, 0.0f, depthOrigin, 1.0f, SpriteEffects.None, 0);
            }
        }
    }
}
